package cz.muni.fi.pb138.eis_core;

import javax.xml.xquery.*;
import net.xqj.basex.BaseXXQDataSource;

/**
 * Provides tools to work with the database
 * more conveniently.
 * 
 * @author Jakub Senko
 */
public class DBTools
{
    private XQDataSource xqds;
    private String username;
    private String password;
    private String database;
    private String file;
    
    private static DBTools instance;
    
    /**
     * Gets the info of the connection. If the connection does not exists, new connection is created.
     * 
     * @return info of the connection
     * @throws XQException
     */
    public static synchronized DBTools getInstance() throws XQException
    {
        if(instance == null)
        {
            instance = new DBTools("localhost", "1984", "admin", "admin", "test", "test.xml");
        }
        
        return instance;
    }

    
    private DBTools(String serverName, String port, String username, String password, String database, String file) throws XQException
    {
        xqds = new BaseXXQDataSource();
        xqds.setProperty("serverName", serverName);
        xqds.setProperty("port", port);
        this.username = username;
        this.password = password;
        this.database = database;
        this.file = file;
    }

    /**
     * !!Remember to close the connection
     * @return connection
     * @throws XQException  
     */
    public synchronized XQConnection getConnection() throws XQException
    {
        return xqds.getConnection(username, password);
    }
    
    /**
     * XQuery injection protection.
     * @param s potentially dangerous input
     * @return sanitized string
     */
    public String sanitize(String s)
    {
        return s.replace("&", "&amp;")
         .replace("'", "&apos;")
         .replace("\"", "&quot;");
    }
    /*
    public String getDatabaseName()
    {
        return database;
    }
    
    public String getFileName()
    {
        return file;
    }
    */
    
    /**
     * Executes given command
     * 
     * @param query command to be executed
     * @throws XQException An exception that provides information on XQJ, XQuery or other errors reported by an XQJ implementation.
     */
    public void executeQueryCommand(String query) throws XQException
    {
        XQConnection xqc = getConnection();
        XQExpression qxe = xqc.createExpression();
        qxe.executeCommand("XQUERY " + query);
        xqc.close();
    }
    
    /**
     * 
     * @return
     * @throws XQException An exception that provides information on XQJ, XQuery or other errors reported by an XQJ implementation.
     */
    public Query getQuery() throws XQException
    {
        return new Query() {
            
            private XQConnection xqc = getConnection();
            private XQExpression xqe = xqc.createExpression();

            public XQResultSequence execute(String s) throws XQException
            {
                return xqe.executeQuery(s);
            }

            public void close() throws XQException
            {
                xqc.close();
            }
        };
    }
    
    /**
     * 
     * @return
     */
    public String getDoc()
    {
        return "db:open('" + database + "', '" + file + "')";
    }
}
